///PHILOTES Source Code.  (C)2012 PhiloLabs
#pragma once

#ifndef __SubMesh_H_
#define __SubMesh_H_

#include "OgrePrerequisites.h"

#include "OgreVertexIndexData.h"
#include "OgreMaterial.h"
#include "OgreRenderOperation.h"
#include "OgreVertexBoneAssignment.h"
#include "OgreAnimationTrack.h"
#include "OgreResourceGroupManager.h"

namespace Ogre {

	
	
	
	class _OgreExport SubMesh : public MemAlloc_Resource
    {
        friend class Mesh;
        friend class MeshSerializerImpl;
        friend class MeshSerializerImpl_v1_2;
        friend class MeshSerializerImpl_v1_1;
    public:
        SubMesh();
        ~SubMesh();


        /// Indicates if this submesh shares vertex data with other meshes or whether it has it's own vertices.
        bool useSharedVertices;

        /// The render operation type used to render this submesh
        RenderOperation::OperationType operationType;

        
        VertexData *vertexData;

        /// Face index data
        IndexData *indexData;

        
        typedef vector<unsigned short>::type IndexMap;
        IndexMap blendIndexToBoneIndexMap;

		typedef vector<IndexData*>::type LODFaceList;
		LODFaceList mLodFaceList;

        
        vector<Vector3>::type extremityPoints;

        /// Reference to parent Mesh (not a smart pointer so child does not keep parent alive).
        Mesh* parent;

        /// Sets the name of the Material which this SubMesh will use
        void setMaterialName(const String& matName, const String& groupName = ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME );
        const String& getMaterialName(void) const;

        
        bool isMatInitialised(void) const;

        
        void _getRenderOperation(RenderOperation& rend, ushort lodIndex = 0);

        
        void addBoneAssignment(const VertexBoneAssignment& vertBoneAssign);

        
        void clearBoneAssignments(void);

        /// Multimap of verex bone assignments (orders by vertex index)
        typedef multimap<size_t, VertexBoneAssignment>::type VertexBoneAssignmentList;
        typedef MapIterator<VertexBoneAssignmentList> BoneAssignmentIterator;

        
        BoneAssignmentIterator getBoneAssignmentIterator(void);

		
		const VertexBoneAssignmentList& getBoneAssignments() { return mBoneAssignments; }


        
        void _compileBoneAssignments(void);

        typedef ConstMapIterator<AliasTextureNamePairList> AliasTextureIterator;
        
        AliasTextureIterator getAliasTextureIterator(void) const;
        
        void addTextureAlias(const String& aliasName, const String& textureName);
        
        void removeTextureAlias(const String& aliasName);
        
        void removeAllTextureAliases(void);
        
        bool hasTextureAliases(void) const { return !mTextureAliases.empty(); }
        
        size_t getTextureAliasCount(void) const { return mTextureAliases.size(); }

        
        bool updateMaterialUsingTextureAliases(void);

		
		VertexAnimationType getVertexAnimationType(void) const;
		
		/// Returns whether animation on dedicated vertex data includes normals
		bool getVertexAnimationIncludesNormals() const { return mVertexAnimationIncludesNormals; }


        
        void generateExtremes(size_t count);

				
		bool isBuildEdgesEnabled(void) const { return mBuildEdgesEnabled; }
		void setBuildEdgesEnabled(bool b);

    protected:

        /// Name of the material this SubMesh uses.
        String mMaterialName;

        /// Is there a material yet?
        bool mMatInitialised;

        /// paired list of texture aliases and texture names
        AliasTextureNamePairList mTextureAliases;

        VertexBoneAssignmentList mBoneAssignments;

        /// Flag indicating that bone assignments need to be recompiled
        bool mBoneAssignmentsOutOfDate;

		/// Type of vertex animation for dedicated vertex data (populated by Mesh)
		mutable VertexAnimationType mVertexAnimationType;

		/// Whether normals are included in vertex animation keyframes
		mutable bool mVertexAnimationIncludesNormals;

		/// Is Build Edges Enabled
		bool mBuildEdgesEnabled;

        /// Internal method for removing LOD data
        void removeLodLevels(void);


    };
	
	

} // namespace

#endif


